package se581.banker;
import java.util.HashMap;
import org.apache.log4j.Logger;

import se581.banker.client.QueryClient;
import se581.banker.client.UpdateClient;
import se581.banker.manager.AccountTracker;
import se581.banker.manager.impl.InquiryTracker;
import se581.banker.manager.impl.UpdateTracker;
import se581.banker.processor.Processor;
import se581.banker.service.RegistrationService;
import se581.banker.util.ServerSocketInfo;

/**
 * Main for an AccountSystem Client JVM instance.
 * 
 * This simulates system clients.  This invokes the
 * SimulationEventProxy to read the events file and
 * create clients.
 * 
 * The SimulationEventProxy puts all the events for the
 * tick in the respective clients' event queues.  Then,
 * at each tick the clients wake and process the event
 * of the tick.
 * 
 * 
 * @author mmichalak
 *
 */
public class SimulationClientMain {
	static Logger logger = Logger.getLogger(SimulationClientMain.class.getName());
	
	String instancePortNum = "6789";
	
	SimulationEventProxy simulationEventProxy = null;
	Processor proc1 = null;
	Processor proc2 = null;
	
	RegistrationService regSvc = null;
	/*
	 * NOTE this is a constant used by the clients.  This is static since there is no simple
	 * way to provide this to all the clients.  Realistically clients would have this as 
	 * a config property
	 */
	public static ServerSocketInfo registrationServerInfo = null;
	
	public static void main(String[] args) {
		logger.debug("Starting AccountSimulation Client");	
		
		SimulationClientMain acctInst = new SimulationClientMain();
		
		if (args.length < 2) {
			logger.error("Required param is missing.  Required:  instance_port  registration_host:registration_port");
			return;
		}
		acctInst.instancePortNum = args[0];
		SimulationClientMain.registrationServerInfo = new ServerSocketInfo(args[1]); //server:port
		
		acctInst.setupSimulation();
		
		acctInst.runSimulation();
		

		logger.debug("Ending AccountSimulation Client ");
	}
	
	
	/**
	 * Create all the system objects and set relationships
	 */
	public void setupSimulation() {
		// This is the simulation driver based on the Event file
		simulationEventProxy = new SimulationEventProxy();
		
		// Setup Processor
		proc1 = new Processor("P1");
		AccountTracker updateTracker = new UpdateTracker();
		proc1.setUdpateTracker(updateTracker);
		AccountTracker inquiryTracker = new InquiryTracker();
		proc1.setInquiryTracker(inquiryTracker);
		
		// This provides registration and health services
		regSvc = new RegistrationService();
		simulationEventProxy.setRegSvc(regSvc);

		// Set the collections for the clients
		simulationEventProxy.setUpdateClients( new HashMap<String, UpdateClient>() );
		simulationEventProxy.setInquryClients( new HashMap<String, QueryClient>() );

	}
		
	
	public void runSimulation() {
		simulationEventProxy.readEvents();
	}
	
}
